home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / progjrn / pj_7_2.arc / FORMAT.PAS < prev    next >
Pascal/Delphi Source File  |  1989-02-28  |  6KB  |  249 lines

  1. { sample code fragments from John Newlin's "Disk Formatting" }
  2.  
  3.  AddressFieldType = record
  4.                      TrackNum,HeadNum,SectNum,SizeCode : byte;
  5.                     End;
  6. Const
  7.   MaxSectors = 18;
  8.   Disk360Params : array[0..10] of byte =
  9.      ($DF,$02,$25,$02,$09,$2A,$FF,$50,$F6,$0F,$08);
  10.  
  11. Type
  12.   DiskParameterTableType = Record
  13.                              StepRate, LoadTime, Shutoff,
  14.                              BytesSec, SecTrack, GapLen,           
  15.                              DataLen, FGapLen, FillByte,           
  16.                              SettleTime,StartTime : byte;
  17.                            End;
  18.  
  19. Var
  20.   AddressFields : array[1..MaxSectors] of AddressFieldType;
  21.   RAMTable : DiskParameterTableType absolute $0000:$0078;
  22.   regs   : registers;
  23.  
  24. Begin
  25.   With Regs Do
  26.     Begin
  27.       AH := $18H;                 {set up to call function}
  28.       DL := DriveNum;             {0 = A, 1 = B, etc.}
  29.       CH := NumOfTracks;          {39 or 79 tracks}
  30.       CL := NumOfSectors;         {number of sectors/track}
  31.       Intr($13,Regs);             {call the BIOS}
  32.       if Flags and 1 = 0 the move(mem[ES:DI],RAMTable^,11)
  33.         else move(Disk360Params,RAMTable^,11);
  34.     End;
  35. End;
  36.  
  37.  
  38. Procedure LoadParameterTable;
  39. Var
  40.   i : byte;
  41. Begin
  42.   For i := 1 to NumSectors do
  43.     Begin
  44.       AddressFields[i].HeadNum := 0;
  45.       AddressFields[i].SectNum := i;
  46.       AddressFileds[i].SizeCode[i] := 2;
  47.       AddressFields[i + NumSectors].HeadNum := 1;
  48.       AddressFields[i + NumSectors].SectNum := i;
  49.       AddressFields[i + NumSectors].SizeCode := 2;
  50.     End;
  51. End;
  52.  
  53. Function FormatTrack(Var Params; drive, track, sectors) : word;
  54. var Regs : Registers;
  55.     i : byte;
  56. Begin
  57.   With Regs Do
  58.     Begin
  59.       ES := seg(params);
  60.       BX := ofs(params);
  61.       AH := $05;
  62.       CH := track;
  63.       DL := drive;
  64.       DH := 0;
  65.       AL := sectors;
  66.       For i := 1 to sectors * 2 do Params[i].TrackNum := track;
  67.  
  68.       Intr($13,Regs);
  69.       if Flags and 1 <> 0 then
  70.         begin
  71.           FormatTrack := word(AH);
  72.           exit;
  73.         end;
  74.       DH := 1;
  75.       ES := seg(params);
  76.       BX := ofs(params) + (4 * sectors);
  77.  
  78.       AL := sectors
  79.       AH := 05H;
  80.       Intr($13,Regs);
  81.       if Flags and 1 = 0 then FormatTrack := 0
  82.           else FormatTrack := word(AH);
  83.       End;
  84. End;
  85.  
  86.  
  87. {$L BOOTSEC.BIN}
  88.  
  89. Procedure BootSector; External;
  90.  
  91. Type
  92.   BootType = Array[0..511] of byte;
  93.  
  94. Var
  95.   Boot : ^BootType;
  96.  
  97. Begin
  98.   Boot := @BootSector;
  99.   ......
  100.   ......
  101.  
  102. Const
  103.   Disk360Boot : Array[1..14] of byte =
  104.    ($02,$01,$00,$02,$70,$00,$D0,$02,$FD,$02,$00,$09,$00,$02);
  105.  
  106. Function WriteSector(drive,track,side,
  107.                      sector : byte; var buffer) : boolean;
  108. Var
  109.   Regs : registers;
  110. Begin
  111.   With Regs do
  112.     Begin
  113.       AH := $03;
  114.       AL := 1;
  115.       ES := seg(buffer);
  116.       BX := ofs(buffer);
  117.       CH := track;
  118.       CL := sector;
  119.       DH := side;
  120.       DL := drive;
  121.       Intr($13,Regs);
  122.       WriteSector := flags and 1 = 0;
  123.     End;
  124. End;
  125.  
  126.  
  127. Var
  128.   Fat : Array[2..3] of BootType;
  129.   i : byte;
  130.  
  131. Begin
  132.   FillChar(Fat,sizeof(Fat),0);
  133.   Fat[1] := $FD;  Fat[2] := $FF;  Fat[3] := $FF;
  134.  
  135. For i := 2 to 3 do
  136.   Begin
  137.     if not WriteSector(1,0,0,i,Fat) then;
  138.     if not WriteSector(1,0,0,i+2,Fat) then;
  139.   End;
  140.  
  141.  
  142. Begin
  143.   FillChar(Boot,Sizeof(boot),0);
  144.   For i := 6 to 9 do if WriteSector(1,0,0,i,boot) then;
  145.   For i := 1 to 3 do if WriteSector(1,0,1,i,boot) then;
  146. End;
  147.  
  148. Function VerifyTrack(Drive,Side,Track,Sectors : byte) : boolean;
  149. Var Regs : Registers;
  150. Begin
  151.   With Regs Do
  152.     Begin
  153.       AH := $04;
  154.       AL := Sectors;
  155. CH := Track;
  156. CL := 1;
  157. DH := Side;
  158. DL := Drive;
  159.       Int($13,Regs);
  160.       VerifyTrack := Flags and 1 = 0;
  161.     End;
  162. End;
  163.  
  164. Function DosSector(Side,Track,BiosSector,SPS : byte) : word;
  165. Begin
  166.   DosSector := word(BiosSector - 1) + word(Side * SPS) +
  167.                word(Track * SPS * 2);
  168. End;
  169.  
  170. Function DosCluster(DosSector : word) : word;
  171. Begin
  172.   DosCluster := (DosSector div SPC) - CNAdjust;
  173. End;
  174.  
  175. Function FATOffset(Cluster : word) : word;
  176. Begin
  177.   FATOffset := (Cluster * 3) div 2;
  178. End;
  179.  
  180. Type
  181.   FATType = Array[1..512] of byte;
  182.  
  183. Var
  184.   FAT : array[0..4607] of byte;
  185.   FATSector : array[1..9] of FATType absolute FAT;
  186.   BadCount : word;
  187.  
  188. Procedure MarkFat(ClusterNumber : word);
  189. Var Offset : word;
  190. Begin
  191.   Inc(BadCount);
  192.   Offset := FATOffset(ClusterNumber);
  193.   if odd(ClusterNumber) then
  194.     Begin
  195.       Fat[Offset] := Fat[Offset] or $70;
  196.       Fat[Offset+1] := $FF;
  197.     End
  198.   Else
  199.    Begin
  200.      Fat[Offset] := $F7;
  201.      Fat[Offset+1] := $0F;
  202.   End;
  203. End;
  204.  
  205. Procedure VerifyDisk(Drive,Tracks,Sectors,SPS,FatLen : byte);
  206. Var Trk,Sector,Side : byte;
  207.     LastCN : word;
  208.  
  209. Procedure MarkTrack(Drive,Track,Side : byte);
  210. Var Sector : byte
  211.     DosSect,Cluster : word;
  212. Begin
  213.   For Sector := 1 to Sectors do
  214.     Begin
  215.       DosSec := DosSector(Side,Track,Sector,SPS);
  216.       Cluster := DosCluster(DosSec);
  217.       if Cluster <> LastCN then
  218.         Begin
  219.           MarkFat(Cluster);
  220.           LastCN := Cluster;
  221.         End;
  222.     End;
  223.   End;
  224. End;
  225.  
  226. Begin
  227.   FillChar(Fat,Sizeof(Fat),0);
  228.   BadCount := 0;
  229.   LastCN := 0;
  230.   FAT[0] := $FD;
  231.   FAT[1] := $FF;
  232.   FAT[2] := $FF;
  233.   For Trk := 1 to Tracks do
  234.     Begin
  235.       For Side := 0 to 1 do
  236.         if not VerifyTrack(Drive,Trk,Side,SPS) then
  237.           MarkFat(Drive,Trk,Side);
  238.     End;
  239.   If BadCount > 0 then
  240.     Begin
  241.       For i := 2 to FatLen + 1 do
  242.         Begin
  243.           If WriteSector(Drive,0,0,i,FATSector[i]) then;
  244.           If WriteSecotr(Drive,0,0,i + FatLen,FATSector[i]) then;
  245.         End;
  246.     End;
  247. End;
  248.  
  249.